parameters:
  buildConfig: ''
  archType: ''
  osGroup: ''
  osSubgroup: ''
  container: ''
  runtimeVariant: ''
  framework: net9.0 # Specify the appropriate framework when running release branches (ie net6.0 for release/6.0)
  liveLibrariesBuildConfig: ''
  variables: {}
  runtimeType: 'coreclr'
  pool: ''
  codeGenType: 'JIT'
  projectFile: ''
  runKind: ''
  runJobTemplate: '/eng/pipelines/coreclr/templates/run-performance-job.yml'
  additionalSetupParameters: ''
  logicalMachine: ''
  pgoRunType: ''
  physicalPromotionRunType: ''
  r2rRunType: ''
  experimentName: ''
  javascriptEngine: 'NoJS'
  iOSLlvmBuild: 'False'
  iOSStripSymbols: 'False'
  hybridGlobalization: 'False'
  collectHelixLogsScript: ''
  timeoutInMinutes: 320
  compare: false
  onlySanityCheck: false
  downloadSpecificBuild: null # buildId, pipeline, branchName, project
  perfForkToUse: {} # url, branch
  crossBuild: false

### Perf job

### Each perf job depends on a corresponding build job with the same
### buildConfig and archType.

jobs:
- template: ${{ parameters.runJobTemplate }}
  parameters:
    # Compute job name from template parameters
    jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}_{4}_{5}_{6}_{7}_{8}_{9}_{10}_{11}_{12}_{13}_{14}_{15}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType, parameters.runKind, parameters.logicalMachine, parameters.javascriptEngine, parameters.pgoRunType, parameters.physicalPromotionRunType, parameters.r2rRunType, parameters.experimentName, parameters.iosLlvmBuild, parameters.iosStripSymbols, parameters.hybridGlobalization) }}
    displayName: ${{ format('Performance {0}{1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType, parameters.runKind, parameters.logicalMachine, parameters.javascriptEngine, parameters.pgoRunType, parameters.physicalPromotionRunType, parameters.r2rRunType, parameters.experimentName, parameters.iosLlvmBuild, parameters.iosStripSymbols, parameters.hybridGlobalization) }}
    pool: ${{ parameters.pool }}
    buildConfig: ${{ parameters.buildConfig }}
    archType: ${{ parameters.archType }}
    osGroup: ${{ parameters.osGroup }}
    osSubgroup: ${{ parameters.osSubgroup }}
    runtimeVariant: ${{ parameters.runtimeVariant }}
    liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }}
    runtimeType: ${{ parameters.runtimeType }}
    codeGenType: ${{ parameters.codeGenType }}
    projectFile: ${{ parameters.projectFile }}
    runKind: ${{ parameters.runKind }}
    additionalSetupParameters: ${{ parameters.additionalSetupParameters }}
    container: ${{ parameters.container }}
    logicalmachine: ${{ parameters.logicalmachine }}
    pgoRunType: ${{ parameters.pgoRunType }}
    physicalPromotionRunType: ${{ parameters.physicalPromotionRunType }}
    r2rRunType: ${{ parameters.r2rRunType }}
    experimentName: ${{ parameters.experimentName }}
    javascriptEngine: ${{ parameters.javascriptEngine }}
    iosLlvmBuild: ${{ parameters.iosLlvmBuild }}
    iosStripSymbols: ${{ parameters.iosStripSymbols }}
    hybridGlobalization: ${{ parameters.hybridGlobalization }}
    timeoutInMinutes: ${{ parameters.timeoutInMinutes }}

    ${{ if and(eq(parameters.runtimeType, 'wasm'), eq(parameters.codeGenType, 'aot')) }}:
      helixTypeSuffix: '/wasm/aot'
    ${{ if and(eq(parameters.runtimeType, 'wasm'), ne(parameters.codeGenType, 'aot')) }}:
      helixTypeSuffix: '/wasm'

    collectHelixLogsScript: ${{ parameters.collectHelixLogsScript }}

    # Test job depends on the corresponding build job
    ${{ if eq(parameters.downloadSpecificBuild.buildId, '') }}:
      dependsOn:
      - ${{ if not(in(parameters.runtimeType, 'AndroidMono', 'iOSMono', 'iOSNativeAOT', 'wasm')) }}:
        - ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, 'coreclr') }}
      - ${{ if and(eq(parameters.runtimeType, 'mono'), ne(parameters.codeGenType, 'AOT')) }}:
        - ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, 'mono') }}
      - ${{ if eq(parameters.runtimeType, 'wasm')}}:
        - ${{ format('build_{0}{1}_{2}_{3}_{4}_{5}', 'browser', '', 'wasm', 'linux', parameters.buildConfig, parameters.runtimeType) }}
      - ${{ if and(eq(parameters.codeGenType, 'AOT'), ne(parameters.runtimeType, 'wasm'))}}:
        - ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.codeGenType) }}
      - ${{ if eq(parameters.runtimeType, 'AndroidMono')}}:
        - ${{ 'build_android_arm64_release_AndroidMono' }}
        - ${{ 'Build_ios_arm64_release_PerfBDNApp' }}
      - ${{ if eq(parameters.runtimeType, 'iOSMono')}}:
        - ${{ 'build_ios_arm64_release_iOSMono' }}
      - ${{ if eq(parameters.runtimeType, 'iOSNativeAOT')}}:
        - ${{ 'build_ios_arm64_release_iOSNativeAOT' }}

    ${{ if and(eq(parameters.osGroup, 'windows'), not(in(parameters.runtimeType, 'AndroidMono', 'iOSMono', 'iOSNativeAOT'))) }}:
      ${{ if eq(parameters.runtimeType, 'mono') }}:
        extraSetupParameters: -Architecture ${{ parameters.archType }} -MonoDotnet $(Build.SourcesDirectory)\.dotnet-mono
      ${{ if eq(parameters.runtimeType, 'coreclr') }}:
        extraSetupParameters: -CoreRootDirectory $(Build.SourcesDirectory)\artifacts\tests\coreclr\${{ parameters.osGroup }}.${{ parameters.archType }}.Release\Tests\Core_Root -Architecture ${{ parameters.archType }}
    ${{ if and(ne(parameters.osGroup, 'windows'), not(in(parameters.runtimeType, 'AndroidMono', 'iOSMono', 'iOSNativeAOT'))) }}:
      ${{ if and(eq(parameters.runtimeType, 'mono'), ne(parameters.codeGenType, 'AOT')) }}:
        extraSetupParameters: --architecture ${{ parameters.archType }} --monodotnet $(Build.SourcesDirectory)/.dotnet-mono
      ${{ if and(eq(parameters.runtimeType, 'wasm'), ne(parameters.codeGenType, 'AOT')) }}:
        extraSetupParameters: --architecture ${{ parameters.archType }} --wasmbundle $(librariesDownloadDir)/bin/wasm --javascriptengine ${{ parameters.javascriptEngine }} --hybridglobalization ${{ parameters.hybridGlobalization }} $(extraSetupParametersSuffix)
      ${{ if and(eq(parameters.runtimeType, 'wasm'), eq(parameters.codeGenType, 'AOT')) }}:
        extraSetupParameters: --architecture ${{ parameters.archType }} --wasmbundle $(librariesDownloadDir)/bin/wasm --wasmaot --javascriptengine ${{ parameters.javascriptEngine }} $(extraSetupParametersSuffix)
      ${{ if and(eq(parameters.codeGenType, 'AOT'), ne(parameters.runtimeType, 'wasm')) }}:
        extraSetupParameters: --architecture ${{ parameters.archType }} --monoaot $(librariesDownloadDir)/bin/aot --llvm
      ${{ if and(eq(parameters.runtimeType, 'coreclr'), ne(parameters.osSubGroup, '_musl')) }}:
        extraSetupParameters: --corerootdirectory $(Build.SourcesDirectory)/artifacts/tests/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.Release/Tests/Core_Root --architecture ${{ parameters.archType }}
      ${{ if and(eq(parameters.runtimeType, 'coreclr'), eq(parameters.osSubGroup, '_musl')) }}:
        extraSetupParameters: --corerootdirectory $(Build.SourcesDirectory)/artifacts/tests/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.Release/Tests/Core_Root --architecture ${{ parameters.archType }} --alpine
    ${{ if in(parameters.runtimeType, 'AndroidMono') }}:
      extraSetupParameters: -Architecture ${{ parameters.archType }} -AndroidMono
    ${{ if in(parameters.runtimeType, 'iOSMono') }}:
      extraSetupParameters: --architecture ${{ parameters.archType }} --iosmono --iosllvmbuild ${{ parameters.iOSLlvmBuild }} --iosstripsymbols ${{ parameters.iOSStripSymbols }} --hybridglobalization ${{ parameters.hybridGlobalization }}
    ${{ if in(parameters.runtimeType, 'iOSNativeAOT') }}:
      extraSetupParameters: --architecture ${{ parameters.archType }} --iosnativeaot --iosllvmbuild ${{ parameters.iOSLlvmBuild }} --iosstripsymbols ${{ parameters.iOSStripSymbols }} --hybridglobalization ${{ parameters.hybridGlobalization }}

    variables:
    - ${{ each variable in parameters.variables }}:
      - ${{insert}}: ${{ variable }}
    - _crossBuildPropertyArg: ''

    - name: _compareArg
      ${{ if eq(parameters.compare, 'true') }}:
        value: '--compare'
    - name: _onlySanityCheckArg
      ${{ if eq(parameters.onlySanityCheck, 'true') }}:
        value: '--only-sanity'
    - name: _perfForkArg
      ${{ if ne(parameters.perfForkToUse.url, '') }}:
        value: --perffork ${{ parameters.perfForkToUse.url }} --perfforkbranch ${{ coalesce(parameters.perfForkToUse.branch, 'main') }}

    - name: extraSetupParametersSuffix
      value: "$(_compareArg) $(_onlySanityCheckArg) $(_perfForkArg)"

    - ${{ if eq(parameters.crossBuild, true) }}:
      - _crossBuildPropertyArg: '-cross'

    - name: librariesDownloadDir
      value: '$(Build.SourcesDirectory)/artifacts'

    - template: /eng/pipelines/common/templates/runtimes/native-test-assets-variables.yml
      parameters:
        runtimeFlavor: coreclr
        testGroup: ${{ parameters.testGroup }}
        liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }}

    frameworks:
      - ${{ parameters.framework }}
    steps:
    # Extra steps that will be passed to the performance template and run before sending the job to helix (all of which is done in the template)
    - script: |
        $(Build.SourcesDirectory)/eng/common/msbuild.sh $(Build.SourcesDirectory)/eng/testing/performance/add_properties_to_pipeline.proj /t:SetVariables
      displayName: Add Properties To Pipeline Env

    # Download wasm
    - ${{ if eq(parameters.runtimeType, 'wasm') }}:
      - ${{ if eq(parameters.downloadSpecificBuild.buildId, '') }}:
        - template: /eng/pipelines/common/download-artifact-step.yml
          parameters:
            unpackFolder: $(librariesDownloadDir)/BrowserWasm
            artifactFileName: BrowserWasm.tar.gz
            artifactName: BrowserWasm
            displayName: BrowserWasm
      - ${{ if ne(parameters.downloadSpecificBuild.buildId, '') }}:
        - template: /eng/pipelines/common/download-specific-artifact-step.yml
          parameters:
            unpackFolder: $(librariesDownloadDir)/BrowserWasm
            artifactFileName: BrowserWasm.tar.gz
            artifactName: BrowserWasm
            displayName: BrowserWasm
            ${{ insert }}: ${{ parameters.downloadSpecificBuild }}

      - script: >-
          mkdir -p $(librariesDownloadDir)/bin/wasm/wasm-data &&
          mkdir -p $(librariesDownloadDir)/bin/wasm/dotnet &&
          cp -r $(librariesDownloadDir)/BrowserWasm/staging/dotnet-latest/* $(librariesDownloadDir)/bin/wasm/dotnet &&
          cp -r $(librariesDownloadDir)/BrowserWasm/staging/built-nugets $(librariesDownloadDir)/bin/wasm &&
          cp src/mono/browser/test-main.js $(librariesDownloadDir)/bin/wasm/wasm-data/test-main.js &&
          find $(librariesDownloadDir)/bin/wasm -type d &&
          find $(librariesDownloadDir)/bin/wasm -type f -exec chmod 664 {} \;
        displayName: "Create wasm directory (Linux)"
    - ${{ elseif eq(parameters.codeGenType, 'AOT') }}:
      # Download mono AOT
      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
          artifactFileName: 'BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)_coreclr$(archiveExtension)'
          artifactName: 'BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)_coreclr'
          displayName: 'Runtime artifacts'

      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(librariesDownloadDir)/LinuxMonoAOT
          artifactFileName: LinuxMonoAOT${{ parameters.archType }}.tar.gz
          artifactName: LinuxMonoAOT${{ parameters.archType }}
          displayName: AOT Mono Artifacts

      - script: "mkdir -p $(librariesDownloadDir)/bin/aot;mkdir -p $(librariesDownloadDir)/bin/aot/pack;cp -r $(librariesDownloadDir)/LinuxMonoAOT/artifacts/bin/mono/linux.${{ parameters.archType }}.Release/cross/linux-${{ parameters.archType }}/* $(librariesDownloadDir)/bin/aot;cp -r $(librariesDownloadDir)/LinuxMonoAOT/artifacts/bin/microsoft.netcore.app.runtime.linux-${{ parameters.archType }}/Release/* $(librariesDownloadDir)/bin/aot/pack"
        displayName: "Create aot directory (Linux)"
    - ${{ elseif in(parameters.runtimeType, 'coreclr', 'mono') }}:
      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
          artifactFileName: 'BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)_${{ parameters.runtimeType }}$(archiveExtension)'
          artifactName: 'BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)_${{ parameters.runtimeType }}'
          displayName: 'Runtime artifacts'

    - ${{ elseif eq(parameters.runtimeType, 'AndroidMono')}}:
      # Download artifacts for Android Testing
      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(Build.SourcesDirectory)/androidHelloWorld
          cleanUnpackFolder: false
          artifactFileName: 'AndroidMonoarm64.tar.gz'
          artifactName: 'AndroidMonoarm64'
          displayName: 'Mono Android HelloWorld'
      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(Build.SourcesDirectory)
          cleanUnpackFolder: false
          artifactFileName: 'AndroidBDNApk.tar.gz'
          artifactName: 'AndroidBDNApk'
          displayName: 'Mono Android BDN Apk'

    # Download iOSMono and Native AOT tests
    - ${{ elseif or(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.runtimeType, 'iOSNativeAOT')) }}:
      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(Build.SourcesDirectory)/iosHelloWorld
          cleanUnpackFolder: false
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'False'), eq(parameters.iOSStripSymbols, 'False')) }}:
            artifactName: 'iOSSampleAppNoLLVMSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
            artifactFileName: 'iOSSampleAppNoLLVMSymbolsHybridGlobalization${{parameters.hybridGlobalization}}.zip'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'False'), eq(parameters.iOSStripSymbols, 'True')) }}:
            artifactName: 'iOSSampleAppNoLLVMNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
            artifactFileName: 'iOSSampleAppNoLLVMNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}.zip'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'True'), eq(parameters.iOSStripSymbols, 'False')) }}:
            artifactName: 'iOSSampleAppLLVMSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
            artifactFileName: 'iOSSampleAppLLVMSymbolsHybridGlobalization${{parameters.hybridGlobalization}}.zip'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'True'), eq(parameters.iOSStripSymbols, 'True')) }}:
            artifactName: 'iOSSampleAppLLVMNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
            artifactFileName: 'iOSSampleAppLLVMNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}.zip'
          ${{ if and(eq(parameters.runtimeType, 'iOSNativeAOT'), eq(parameters.iOSStripSymbols, 'False')) }}:
            artifactName: 'iOSSampleAppSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
            artifactFileName: 'iOSSampleAppSymbolsHybridGlobalization${{parameters.hybridGlobalization}}.zip'
          ${{ if and(eq(parameters.runtimeType, 'iOSNativeAOT'), eq(parameters.iOSStripSymbols, 'True')) }}:
            artifactName: 'iOSSampleAppNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
            artifactFileName: 'iOSSampleAppNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}.zip'
          displayName: 'iOS Sample App'
      # same artifact as above but don't extract .zip
      - task: DownloadBuildArtifacts@0
        displayName: 'Download iOS Sample App'
        inputs:
          buildType: current
          downloadType: single
          downloadPath: '$(Build.SourcesDirectory)/iosHelloWorldZip'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'False'), eq(parameters.iOSStripSymbols, 'False')) }}:
            artifactName: 'iOSSampleAppNoLLVMSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'False'), eq(parameters.iOSStripSymbols, 'True')) }}:
            artifactName: 'iOSSampleAppNoLLVMNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'True'), eq(parameters.iOSStripSymbols, 'False')) }}:
            artifactName: 'iOSSampleAppLLVMSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
          ${{ if and(eq(parameters.runtimeType, 'iOSMono'), eq(parameters.iOSLlvmBuild, 'True'), eq(parameters.iOSStripSymbols, 'True')) }}:
            artifactName: 'iOSSampleAppLLVMNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
          ${{ if and(eq(parameters.runtimeType, 'iOSNativeAOT'), eq(parameters.iOSStripSymbols, 'False')) }}:
            artifactName: 'iOSSampleAppSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
          ${{ if and(eq(parameters.runtimeType, 'iOSNativeAOT'), eq(parameters.iOSStripSymbols, 'True')) }}:
            artifactName: 'iOSSampleAppNoSymbolsHybridGlobalization${{parameters.hybridGlobalization}}'
          checkDownloadedFiles: true

    # Create Core_Root
    - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(buildConfig) $(archType) generatelayoutonly $(librariesOverrideArg) $(_crossBuildPropertyArg)
      displayName: Create Core_Root
      condition: and(succeeded(), ne(variables.runtimeFlavorName, 'Mono'), not(in('${{ parameters.runtimeType }}', 'wasm', 'AndroidMono', 'iOSMono', 'iOSNativeAOT')))

    - task: CopyFiles@2
      displayName: Create .dotnet-mono folder
      inputs:
        SourceFolder: $(Build.SourcesDirectory)/artifacts/bin/testhost/${{ parameters.framework }}-$(osGroup)-$(buildConfigUpper)-$(archType)
        TargetFolder: $(Build.SourcesDirectory)/.dotnet-mono
      condition: and(succeeded(), eq(variables.runtimeFlavorName, 'Mono'), ne(variables.osGroup, 'windows'), notIn('${{ parameters.runtimeType }}', 'wasm', 'AndroidMono', 'iOSMono', 'iOSNativeAOT'))

    - task: CopyFiles@2
      displayName: Copy corerun to .dotnet-mono
      inputs:
        SourceFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)
        Contents: 'corerun*'
        TargetFolder: $(Build.SourcesDirectory)/.dotnet-mono/shared/Microsoft.NETCore.App/$(productVersion)
      condition: and(succeeded(), eq(variables.runtimeFlavorName, 'Mono'), ne(variables.osGroup, 'windows'), notIn('${{ parameters.runtimeType }}', 'wasm', 'AndroidMono', 'iOSMono', 'iOSNativeAOT'))
